home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 49 / Amiga Format CD49 (2000-01-17)(Future Publishing)(GB)(Track 1 of 3)[!][issue 2000-02].iso / -serious- / misc / shellscr / src / args.e next >
Text File  |  1999-11-30  |  6KB  |  205 lines

  1. /****** args.m/--overview-- *******************************************
  2. *   PURPOSE
  3. *       To provide ReadArgs() parsing for both CLI and WB.
  4. *   OVERVIEW
  5. *       AmigaDOS 2.0 has a very powerful argument parser known as
  6. *       ReadArgs(). It allows you to specify a simple template,
  7. *       which describes how arguments will be parsed and will fill
  8. *       an array of LONGs.
  9. *
  10. *       This module provides a readargs() call, which uses the
  11. *       Workbench startup message to go through a list of selected icons'
  12. *       tooltypes, and matches those tooltypes like arguments on the
  13. *       command line.
  14. *
  15. *       Used in ShellScr by Kyzer/CSG
  16. *
  17. ****************************************************************************
  18. *
  19. *
  20. */
  21.  
  22. ->example:
  23. ->  IF rdargs := readargs('CX_PRIORITY/N, CX_POPKEY, CX_POPUP/S',
  24. ->                       args:=NEW [0,0,0], wbmessage)
  25. ->
  26. ->    cx_pri := IF args[0] THEN Long(args[0]) ELSE 0
  27. ->    hotkey := IF args[1] THEN args[1] ELSE 'ctrl alt del'
  28. ->    popup  := args[2]
  29. ->    [....]
  30. ->    FreeArgs(rdargs)
  31. ->  ENDIF
  32.  
  33. -> FIXES:
  34. -> - (06.04.98) Gags when directories are selected. Fixed.
  35. -> - (04.05.98) Fixed memory-trashing bug.
  36. -> - (02.09.98) Stops quoting already-quoted strings
  37.  
  38. -> TODO:
  39. -> - support =YES and =NO tooltypes in switches
  40. -> - special case (list of icon names) to /M switched variables
  41.  
  42. OPT MODULE,OSVERSION=36
  43.  
  44. MODULE 'icon', 'dos/rdargs', 'workbench/startup', 'workbench/workbench'
  45. DEF iconbase
  46.  
  47. -> Basically, we run through all the selected icons' tooltypes from
  48. -> first (our own icon) to last. if the left part of a tooltype
  49. -> (in 'BLA=FISH', the left part is 'BLA') is judged by DOS to be
  50. -> a keyword from the template (this includes parsing aliases for
  51. -> keywords) then we insert it and its right part (if there is one)
  52. -> into a list in the appropriate place, which can overwrite tooltypes
  53. -> already there (eg, selected icons override default settings in our
  54. -> own icon). Once we have this list of keywords and values, we can make
  55. -> a single string with all these keywords and values, and give it to
  56. -> ReadArgs.
  57.  
  58. -> The code that splits a tooltype into left and right parts is clever
  59. -> enough to ignore 'disabled' tooltypes which begin with '(', and also
  60. -> ignores tooltypes beginning IM1= or IM2= for performance reasons (NewIcons
  61. -> contain a lot of these tooltypes for their icon data)
  62.  
  63. EXPORT PROC readargs(template:PTR TO CHAR, args, wbmsg:PTR TO wbstartup) HANDLE
  64.   DEF rdargs=NIL, tooltype, name, val, m, n, arg, dir, len,
  65.       arglst=NIL:PTR TO LONG,     -> a list to all our args and their values
  66.       dobj=NIL:PTR TO diskobject, -> diskobject of 'current icon'
  67.       tooltypes:PTR TO LONG       -> tooltypes of 'current icon'
  68.  
  69.   -> If we were run from shell, then just parse as normal
  70.   IF wbmsg = NIL THEN RETURN ReadArgs(template, args, NIL)
  71.  
  72.   -> make sure icon.library is available
  73.   IF (iconbase := OpenLibrary('icon.library', 36))=NIL THEN Raise("LIB")
  74.  
  75.   -> make a big enough list to hold all name/value pairs for template
  76.   IF (arglst := List(len :=getlistlen(template)))=NIL THEN Raise("MEM")
  77.   DEC len
  78.  
  79.   -> Go through all tooltypes in all selected icons
  80.   FOR m := 0 TO wbmsg.numargs - 1
  81.     dir := CurrentDir(wbmsg.arglist[m].lock)
  82.     dobj := GetDiskObject(wbmsg.arglist[m].name)
  83.     CurrentDir(dir)
  84.  
  85.     IF dobj
  86.       IF tooltypes := dobj.tooltypes
  87.         WHILE tooltype := tooltypes[]++
  88.           -> split up tooltype
  89.           name, val := ttsplit(tooltype)
  90.           IF name
  91.             -> if in template, place into appropriate list entry
  92.             IF (arg := FindArg(template, name)) <> -1
  93.               n := Shl(arg, 1)
  94.               IF arg := arglst[ n ] THEN DisposeLink(arg)
  95.               IF arg := arglst[n+1] THEN DisposeLink(arg)
  96.               arglst[ n ] := name
  97.               arglst[n+1] := val
  98.             ELSE
  99.               IF name THEN DisposeLink(name)
  100.               IF val  THEN DisposeLink(val)
  101.             ENDIF
  102.           ENDIF
  103.         ENDWHILE
  104.       ENDIF
  105.       FreeDiskObject(dobj); dobj := NIL
  106.     ENDIF
  107.   ENDFOR
  108.  
  109.   -> calculate length of final 'arg string' to be parsed by ReadArgs()
  110.   m := 0
  111.   FOR n := 0 TO len DO IF arg := arglst[n] THEN m := m + 3 + EstrLen(arg)
  112.  
  113.   IF (m := String(m))=NIL THEN Raise("MEM")
  114.   StrCopy(m, '')
  115.  
  116.   -> concatenate final arg settings into one big string
  117.   FOR n:=0 TO len
  118.     IF arg := arglst[n]
  119.       -> append either 'arg ' or '"arg" ' if arg has spaces in it
  120.       IF (InStr(arg, ' ') = -1) AND (arg[] <> "\q")
  121.         StrAdd(m, arg)
  122.         StrAdd(m, ' ')
  123.       ELSE        
  124.         StrAdd(m, '"')
  125.         StrAdd(m, arg)
  126.         StrAdd(m, '" ')
  127.       ENDIF
  128.     ENDIF
  129.   ENDFOR
  130.  
  131.   -> perform the ReadArgs call on our constructed string
  132.   rdargs := ReadArgs(template, args,
  133.     [m, EstrLen(m), 0, NIL, NIL, 0, NIL, RDAF_NOPROMPT]
  134.   )
  135.  
  136.   -> throw away big string
  137.   DisposeLink(m)
  138.  
  139. EXCEPT DO
  140.   IF arglst
  141.     FOR n := 0 TO len
  142.       IF arg := arglst[n] THEN DisposeLink(arg)
  143.     ENDFOR
  144.     DisposeLink(arglst)
  145.   ENDIF
  146.  
  147.   IF dobj     THEN FreeDiskObject(dobj)
  148.   IF iconbase THEN CloseLibrary(iconbase); iconbase := NIL
  149.  
  150.   ReThrow()
  151. ENDPROC rdargs
  152.  
  153.  
  154.  
  155. PROC ttsplit(s:PTR TO CHAR)
  156.   -> of something 'blah=foo', returns 'blah', 'foo'
  157.   -> of something 'blah', returns 'blah', NIL
  158.   -> of something beginning '(', 'IM1=' or 'IM2=', returns NIL, NIL
  159.  
  160.   DEF div, len, l, r
  161.  
  162.   -> ignore disabled tooltypes, newicon tooltypes, and blank ones
  163.   IF s = NIL THEN RETURN NIL, NIL
  164.   IF (s[]="(") OR (s[]="\0") OR
  165.      StrCmp(s, 'IM1=', 4) OR StrCmp(s, 'IM2=', 4) THEN
  166.     RETURN NIL, NIL
  167.  
  168.   len := StrLen(s)
  169.   div := InStr(s, '=') -> find '=' divisor
  170.  
  171.   IF div = -1
  172.     -> no '=' present in string - return copy of left half
  173.     IF l := String(len) THEN StrCopy(l, s)
  174.     RETURN l, NIL
  175.   ENDIF
  176.  
  177.   -> allocate left and right strings
  178.   l := String(div + 1)
  179.   r := String(len - div)
  180.  
  181.   -> if either string allocation failed, free either and return NIL
  182.   IF (l AND r)=NIL
  183.     IF l THEN DisposeLink(l)
  184.     IF r THEN DisposeLink(r)
  185.     RETURN NIL, NIL
  186.   ENDIF
  187.  
  188.   MidStr(l, s, 0, div) -> copy left of '=' to l
  189.   MidStr(r, s, div+1) -> copy right of '=' to r
  190. ENDPROC l, r
  191.  
  192. PROC getlistlen(template)
  193.     MOVEQ    #1, D0
  194.     MOVE.L    template, A0
  195. __cnt:    MOVE.B    (A0)+, D1
  196.     BEQ.S    __end
  197.     CMP.B    #",", D1
  198.     BNE.S    __cnt
  199.     ADDQ    #1, D0
  200.     BRA.S    __cnt
  201. __end:    ASL.W    #1, D0
  202. ENDPROC D0
  203.